package com.nanfangzhe.shirodemo.config;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.nanfangzhe.shirodemo.entity.UUser;
import com.nanfangzhe.shirodemo.service.URoleService;
import com.nanfangzhe.shirodemo.service.UUserService;

public class MyShiroRealm extends AuthorizingRealm {
	private static final Logger LOGGER = LoggerFactory.getLogger(MyShiroRealm.class);
	@Autowired
	private UUserService userService;
	
	@Autowired
	private URoleService roleService;

	/**
	 * 授权逻辑
	 * 
	 * @param principalCollection
	 * @return
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		System.out.println("权限认证方法：MyShiroRealm.doGetAuthenticationInfo()");
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		// 拿到当前登录的这个对象
		Subject subject = SecurityUtils.getSubject();
		UUser currentUser = (UUser) subject.getPrincipal();

		// 根据用户ID查询角色（role），放入到Authorization里。
		/*
		 * Map<String, Object> map = new HashMap<String, Object>();
		 * map.put("user_id", userId); List<SysRole> roleList =
		 * sysRoleService.selectByMap(map); Set<String> roleSet = new
		 * HashSet<String>(); for(SysRole role : roleList){
		 * roleSet.add(role.getType()); }
		 */
		// 实际开发，当前登录用户的角色和权限信息是从数据库来获取的，我这里写死是为了方便测试
		Set<String> roleSet = new HashSet<String>();
		List<String> roles = userService.getRoles(currentUser.getId());
		roles.forEach(role -> {
			roleSet.add(role);
		});
		info.setRoles(roleSet);
		// 根据用户ID查询权限（permission），放入到Authorization里。
		/*
		 * List<SysPermission> permissionList =
		 * sysPermissionService.selectByMap(map); Set<String> permissionSet =
		 * new HashSet<String>(); for(SysPermission Permission :
		 * permissionList){ permissionSet.add(Permission.getName()); }
		 */
		Set<String> permSet = new HashSet<String>();
		List<String> perms = userService.getPerms(currentUser.getId());
		perms.forEach(perm->{
			perm = perm.replace("perms[", "");
			perm = perm.replace("]", "");
			permSet.add(perm);
//			info.addStringPermission(perm);
		});
		info.setStringPermissions(permSet);
		return info;
	}

	/**
	 * 认证信息.(身份验证) : Authentication 是用来验证用户身份
	 * 
	 * @param token
	 * @return
	 * @throws AuthenticationException
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

		// 当前登录的token信息
		UsernamePasswordToken userToken = (UsernamePasswordToken) token;

		// 从数据库获取对应用户名密码的用户
		UUser user = userService.getByUsername(userToken.getUsername());
        if (user == null) {
            LOGGER.info("用户不存在");
            //返回null，底层抛出异常：UnKnowAccountException
            return null;
        }
        if (user.getStatus() == 0) {
            /**
             * 如果用户的status为禁用。那么就抛出<code>DisabledAccountException</code>
             */
            throw new DisabledAccountException();
        }
		return new SimpleAuthenticationInfo(user, user.getPassword(), "");
	}
}
